package cn.portx.job;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.apache.commons.lang.time.DateUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.bstek.bdf3.dorado.jpa.JpaUtil;
import com.bstek.bdf3.saas.Constants;
import com.bstek.bdf3.saas.SaasUtils;
import com.bstek.bdf3.saas.command.Command;
import com.bstek.bdf3.saas.command.CommandNeedReturn;
import com.bstek.bdf3.saas.domain.Organization;
import com.bstek.bdf3.saas.service.DataSourceService;
import com.bstek.bdf3.saas.service.EntityManagerFactoryService;

import cn.portx.entity.Message;
import cn.portx.entity.Order;
import cn.portx.frame.entity.Company;

@Component
public class FinanceMonitorScheduleJob implements InitializingBean {

	@Autowired
	private EntityManagerFactoryService entityManagerFactoryService;
	@Autowired
	private DataSourceService dataSourceService;
	private int maxDay = 15;
	private int startDay = 3;

//	@Scheduled(fixedDelay = 10000)
//	@Scheduled(cron = "0 0/2 * * * ?") /* 每隔2分钟执行一次 */
	@Scheduled(cron = "0 0 2 * * ?") /* 半夜2点执行一次 */
	public void monitor() {
		List<Organization> list = SaasUtils.doNonQuery(new CommandNeedReturn<List<Organization>>() {

			@Override
			public List<Organization> execute() {
				List<Company> companies = JpaUtil.linq(Company.class).collect(Organization.class, "orgId").equal("enable", "1").notEqual("orgId", Constants.MASTER).list();
				List<Organization> list = new ArrayList<Organization>();
				for (Company c : companies) {
					list.add(c.getOrg());
				}
				return list;
			}
		});
		for (Organization org : list) {

			Task task = new Task();
			try {
				SaasUtils.doNonQuery(org.getId(), task);
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			} finally {
				EntityManagerFactory emf = task.getEmf();
				DataSource ds = dataSourceService.getDataSource(org);
				entityManagerFactoryService.removeEntityManagerFactory(org);
				if (emf != null && emf.isOpen()) {
					emf.close();
				}
				if (ds != null) {
					//org.apache.tomcat.jdbc.pool.DataSource@39098de1{ConnectionPool[defaultAutoCommit=null; defaultReadOnly=null; defaultTransactionIsolation=-1; defaultCatalog=null; driverClassName=com.mysql.jdbc.Driver; maxActive=100; maxIdle=100; minIdle=10; initialSize=10; maxWait=30000; testOnBorrow=false; testOnReturn=false; timeBetweenEvictionRunsMillis=5000; numTestsPerEvictionRun=0; minEvictableIdleTimeMillis=60000; testWhileIdle=false; testOnConnect=false; password=********; url=jdbc:mysql://localhost:3306/CC0; username=root; validationQuery=null; validationQueryTimeout=-1; validatorClassName=null; validationInterval=3000; accessToUnderlyingConnectionAllowed=true; removeAbandoned=false; removeAbandonedTimeout=60; logAbandoned=false; connectionProperties=null; initSQL=null; jdbcInterceptors=null; jmxEnabled=true; fairQueue=true; useEquals=true; abandonWhenPercentageFull=0; maxAge=0; useLock=false; dataSource=null; dataSourceJNDI=null; suspectTimeout=0; alternateUsernameAllowed=false; commitOnReturn=false; rollbackOnReturn=false; useDisposableConnectionFacade=true; logValidationErrors=false; propagateInterruptState=false; ignoreExceptionOnPreLoad=false; useStatementFacade=true; }
					if (ds instanceof org.apache.tomcat.jdbc.pool.DataSource) {
						org.apache.tomcat.jdbc.pool.DataSource dataSource = (org.apache.tomcat.jdbc.pool.DataSource) ds;
						dataSource.close(true);
					}
				}
			}

		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
	}

	private class Task implements Command {

		private EntityManagerFactory emf;

		@SuppressWarnings("finally")
		@Override
		public void execute() {
			emf = JpaUtil.getEntityManagerFactory(Order.class);
			EntityManager em = JpaUtil.getEntityManager(Order.class);
			Session session = em.unwrap(Session.class);

			String sql = "SELECT\n" + "	t.*, o.order_no_,\n" + "	o.create_user_,\n" + "	o.type_,\n" + "	o.id_\n" + "FROM\n" + "	(\n" + "		SELECT\n"
					+ "			min(oe.jszt_) AS jszt_,\n" + "			oe.order_id_\n" + "		FROM\n" + "			t_order_expense oe\n" + "		GROUP BY\n"
					+ "			oe.order_id_\n" + "	) t\n" + "INNER JOIN t_order o ON t.order_id_ = o.id_\n" + "AND o.finance_end_ = 0\n" + "AND t.jszt_ = '2'";
			SQLQuery query = session.createSQLQuery(sql);
			List<Object[]> result = query.list();
			for (Object[] array : result) {
				String jszt = (String) array[0];
				String orderNo = (String) array[1];
				String receiver = (String) array[2];
				String type = (String) array[3];
				String id = (String) array[4];

				sql = "SELECT\n" + "	max(h.hx_date_)\n" + "FROM\n" + "	t_hexiao_log h\n" + "WHERE\n" + "	h.type_ = 0\n" + "AND h.order_expense_id_ IN (\n" + "	SELECT\n"
						+ "		oe.id_\n" + "	FROM\n" + "		t_order_expense oe\n" + "	WHERE\n" + "		oe.order_id_ =:orderId\n" + ")";
				query = session.createSQLQuery(sql);
				query.setString("orderId", id);
				Date maxDate = DateUtils.truncate(query.uniqueResult(), Calendar.DATE);
				Date now = DateUtils.truncate(new Date(), Calendar.DATE);
				long day = (now.getTime() - maxDate.getTime()) / (1000 * 60 * 60 * 24);

				if (day >= maxDay - startDay) {
					if (day < maxDay) {
						Message message = new Message();
						message.setCreateDate(new Date());
						message.setContent("你的" + ("0".equals(type) ? "出口" : "进口") + "订单(" + orderNo + ")所有费用已经结清，将在" + (maxDay - day) + "天后自动财务完结！");
						message.setSender("系统");
						message.setType(0);
						message.setReceiver(receiver);
						session.save(message);
					} else {
						sql = "update t_order set finance_end_=1 where id_=:orderId";
						query = session.createSQLQuery(sql);
						query.setString("orderId", id);
						query.executeUpdate();
					}
				}
			}
		}

		public EntityManagerFactory getEmf() {
			return emf;
		}

	}
}
